package com.tssm.core.util;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Iterator;
import java.util.Stack;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.servlet.http.HttpServletRequest;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class Picfiles {

	/**
	 * 
	 * 
	 * @方法说明: 返回图片流
	 * @param in
	 *            文件流
	 * @param type
	 *            文件的扩展名
	 * @return
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static BufferedImage readImage(InputStream in, String type)
			throws IOException {
		Iterator<ImageReader> readers = ImageIO
				.getImageReadersByFormatName(type);
		ImageReader reader = (ImageReader) readers.next();
		ImageInputStream iis = ImageIO.createImageInputStream(in);
		reader.setInput(iis, true);
		BufferedImage img = reader.read(0);
		return img;
	}

	/**
	 * 
	 * 
	 * @方法说明:读取原图片
	 * @param fileName
	 * @return
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static BufferedImage readImage(String fileName) throws IOException {
		String type = fileName.substring(fileName.lastIndexOf(".") + 1);
		return readImage(new FileInputStream(fileName), type);
	}

	/**
	 * 
	 * 
	 * @方法说明:通过网络文件对象读取文件流
	 * @param url
	 *            网络图片地址
	 * @return
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static BufferedImage readImage(URL url) throws IOException {
		String type = url.toString().substring(
				url.toString().lastIndexOf(".") + 1);
		return readImage(url.openStream(), type);
	}

	/**
	 * 
	 * 
	 * @方法说明:通过文件对象读取文件流
	 * @param file
	 *            文件对象
	 * @return
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static BufferedImage readImage(File file) throws IOException {
		String type = file.getName().substring(
				file.getName().lastIndexOf(".") + 1);
		return readImage(new FileInputStream(file), type);
	}

	/**
	 * 
	 * 
	 * @方法说明:写文件流
	 * @param image
	 *            图片流
	 * @param filename
	 *            文件地址
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void writeImage(BufferedImage image, String filename)
			throws IOException {
		String type = filename.substring(filename.lastIndexOf(".") + 1);
		writeImage(image, type, filename);
	}

	/**
	 * 
	 * 
	 * @方法说明:写文件流
	 * @param image
	 *            图片流
	 * @param type
	 *            图片扩展名
	 * @param filename
	 *            文件地址
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void writeImage(BufferedImage image, String type,
			String filename) throws IOException {
		File f = new File(filename);
		writeImage(image, type, f);
	}

	/**
	 * 
	 * 
	 * @方法说明: 写文件流
	 * @param image
	 *            图片流
	 * @param type
	 *            图片扩展名
	 * @param file
	 *            图片扩展名
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void writeImage(BufferedImage image, String type, File file)
			throws IOException {
		Iterator<ImageWriter> writers = ImageIO
				.getImageWritersByFormatName(type);
		ImageWriter writer = (ImageWriter) writers.next();
		// File f = new File(filename);
		ImageOutputStream ios = ImageIO.createImageOutputStream(file);
		writer.setOutput(ios);
		writer.write(image);
	}

	/**
	 * 
	 * 
	 * @方法说明: 压缩图片
	 * @param srcURL
	 *            原图地址
	 * @param deskURL
	 *            缩略图地址
	 * @param comBase
	 *            压缩基数(宽/高)的最大值
	 * @param scale
	 *            压缩限制(宽/高)比例
	 * @return
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static String saveMinPhoto(String srcURL, String deskURL,
			double comBase, double scale) throws IOException {
		String picwh = null;
		java.io.File srcFile = new java.io.File(srcURL);
		Image src = ImageIO.read(srcFile);
		ImageIO.setUseCache(false);
		// Image src=readImage(srcURL);
		int srcHeight = src.getHeight(null);
		int srcWidth = src.getWidth(null);
		int deskHeight = 180;
		int deskWidth = 200;
		double srcScale = (double) srcHeight / srcWidth;
		if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
			if (srcScale >= scale || 1 / srcScale > scale) {
				if (srcScale >= scale) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			} else {
				if ((double) srcHeight > comBase) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			}
		} else {
			deskHeight = srcHeight;
			deskWidth = srcWidth;
		}
		BufferedImage tag = new BufferedImage(deskWidth, deskHeight,
				BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null);
		FileOutputStream deskImage = new FileOutputStream(deskURL);
		// String imageType = deskURL.substring(deskURL.lastIndexOf("."));
		// if ("gif".equals(imageType.toLowerCase())) {
		// try {
		// GIFEncoder gencoder = new GIFEncoder(tag);
		// gencoder.write(deskImage);
		// } catch (AWTException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// } else {
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(deskImage);
		encoder.encode(tag);
		// }
		deskImage.close();
		picwh = deskWidth + "×" + deskHeight;
		return picwh;
	}

	/**
	 * 
	 * 
	 * @方法说明: 压缩图片
	 * @param srcURL
	 *            原图地址
	 * @param deskURL
	 *            缩略图地址
	 * @param comBase
	 *            压缩基数(宽/高)的最大值
	 * @param scale
	 *            压缩限制(宽/高)比例
	 * @throws IOException
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void addMinPhoto(String srcURL, String deskURL,
			double comBase, double scale) throws IOException {
		java.io.File srcFile = new java.io.File(srcURL);
		Image src = ImageIO.read(srcFile);
		// 图片的实际高度
		int srcHeight = src.getHeight(null);
		// 图片的实际宽度
		int srcWidth = src.getWidth(null);
		// 最小高度
		int deskHeight = 0;
		// 最小宽度
		int deskWidth = 0;
		// 实际图片的(宽/高)比例
		double srcScale = (double) srcHeight / srcWidth;
		// 原图片的宽、高是否大于基数
		if ((double) srcHeight > comBase || (double) srcWidth > comBase) {
			if (srcScale >= scale || 1 / srcScale > scale) {
				if (srcScale >= scale) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			} else {
				if ((double) srcHeight > comBase) {
					deskHeight = (int) comBase;
					deskWidth = srcWidth * deskHeight / srcHeight;
				} else {
					deskWidth = (int) comBase;
					deskHeight = srcHeight * deskWidth / srcWidth;
				}
			}
		} else {
			deskHeight = srcHeight;
			deskWidth = srcWidth;
		}
		BufferedImage tag = new BufferedImage(deskWidth, deskHeight,
				BufferedImage.TYPE_3BYTE_BGR);
		// 绘制缩小后的图
		tag.getGraphics().drawImage(src, 0, 0, deskWidth, deskHeight, null);
		// 输出到文件流
		FileOutputStream deskImage = new FileOutputStream(deskURL);
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(deskImage);
		// 近JPEG编码
		encoder.encode(tag);
		deskImage.close();
	}

	/**
	 * 
	 * 
	 * @方法说明: 获得指定文件夹下的文件大小
	 * @param path
	 *            如:File dir = new
	 *            File("E:/tomcat-5.5/webapps/syhome/upload/aaa");
	 * @return
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static long getSize(String path) {
		String path1 = path.replace("\\", "\\\\");
		File dir = new File(path1);
		if (!dir.exists()) {
			return 0;
		}
		if (dir.isFile()) {
			return dir.length();
		}
		long size = 0;
		Stack<File> fileList = new Stack<File>();
		fileList.push(dir);
		while (!fileList.isEmpty()) {
			File nodeDir = fileList.pop();
			File[] files = nodeDir.listFiles();
			for (int i = 0; i < files.length; i++) {
				if (files[i].isFile()) {
					size += files[i].length();
				} else {
					fileList.push(files[i]);
				}
			}
		}
		return size;
	}

	/**
	 * 
	 * 
	 * @方法说明: 新建文件
	 * @param filePathAndName
	 *            文件路径及名称 如c:/fqf.txt
	 * @param fileContent
	 *            文件内容
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */

	public static void newFile(String filePathAndName, String fileContent) {
		try {
			String filePath = filePathAndName;
			filePath = filePath.toString();
			File myFilePath = new File(filePath);
			if (!myFilePath.exists()) {
				myFilePath.createNewFile();
			}
			FileWriter resultFile = new FileWriter(myFilePath);
			PrintWriter myFile = new PrintWriter(resultFile);
			String strContent = fileContent;
			myFile.println(strContent);
			resultFile.close();
		} catch (Exception e) {
			System.out.println("新建目录操作出错");
			e.printStackTrace();
		}

	}

	/**
	 * 
	 * 
	 * @方法说明: 删除指定路径的文件
	 * @param filePathAndName
	 *            文件路径 文件路径及名称 如c:/fqf.txt
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void delFile(String filePathAndName) {
		try {
			String filePath = filePathAndName;
			filePath = filePath.toString();
			java.io.File myDelFile = new java.io.File(filePath);
			if (myDelFile.exists()) {
				myDelFile.delete();
			}
		} catch (Exception e) {
			System.out.println("删除文件操作出错");
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 删除指定的文件夹（包括里面的文件）
	 * @param folderPath
	 *            文件夹路径 如c:/fqf
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void delFolder(String folderPath) {
		try {
			delAllFile(folderPath); // 删除完里面所有内容
			String filePath = folderPath;
			filePath = filePath.toString();
			java.io.File myFilePath = new java.io.File(filePath);
			myFilePath.delete(); // 删除空文件夹
		} catch (Exception e) {
			System.out.println("删除文件夹操作出错");
			e.printStackTrace();

		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 删除指定文件夹下的所有文件
	 * @param path
	 *            文件夹路径
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void delAllFile(String path) {
		File file = new File(path);
		if (!file.exists()) {
			return;
		}
		if (!file.isDirectory()) {
			return;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (path.endsWith(File.separator)) {
				temp = new File(path + tempList[i]);
			} else {
				temp = new File(path + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
				delFolder(path + "/" + tempList[i]);// 再删除空文件夹
			}
		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 复制单个文件到指定的文件下
	 * @param oldPath
	 *            原文件夹路徑
	 * @param newPath
	 *            目标文件路径
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void copyFile(String oldPath, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			File oldfile = new File(oldPath);
			if (oldfile.exists()) { // 文件存在时
				InputStream inStream = new FileInputStream(oldPath); // 读入原文件
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread; // 字节数 文件大小
					fs.write(buffer, 0, byteread);
				}
				fs.flush();
				fs.close();
				inStream.close();
			}
		} catch (Exception e) {
			System.out.println("复制单个文件操作出错");
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @方法说明：拷贝文件到指定文件夹
	 * @author 徐龙
	 * @date Jun 24, 2010
	 * @param oldPath
	 * @param newPath
	 */
	public static void copyimgtodir(String oldPath, String newPath) {
		try {
			int bytesum = 0;
			int byteread = 0;
			File oldfile = new File(oldPath);
			String flieName = oldPath.substring(oldPath.lastIndexOf("/"));
			newPath += flieName;
			if (oldfile.exists()) { // 文件存在时
				InputStream inStream = new FileInputStream(oldPath); // 读入原文件
				FileOutputStream fs = new FileOutputStream(newPath);
				byte[] buffer = new byte[1444];
				while ((byteread = inStream.read(buffer)) != -1) {
					bytesum += byteread; // 字节数 文件大小
					fs.write(buffer, 0, byteread);
				}
				fs.flush();
				fs.close();
				inStream.close();
			}
		} catch (Exception e) {
			System.out.println("复制单个文件操作出错");
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 复制整个文件夹内容到指定文件夾中
	 * @param oldPath
	 *            原文件夹路徑
	 * @param newPath
	 *            目標文夹件路徑
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void copyFolder(String oldPath, String newPath) {
		try {
			(new File(newPath)).mkdirs(); // 如果文件夹不存在 则建立新文件夹
			File a = new File(oldPath);
			String[] file = a.list();
			File temp = null;
			for (int i = 0; i < file.length; i++) {
				if (oldPath.endsWith(File.separator)) {
					temp = new File(oldPath + file[i]);
				} else {
					temp = new File(oldPath + File.separator + file[i]);
				}
				if (temp.isFile()) {
					FileInputStream input = new FileInputStream(temp);
					FileOutputStream output = new FileOutputStream(newPath
							+ "/" + (temp.getName()).toString());
					byte[] b = new byte[1024 * 5];
					int len;
					while ((len = input.read(b)) != -1) {
						output.write(b, 0, len);
					}
					output.flush();
					output.close();
					input.close();
				}
				if (temp.isDirectory()) {// 如果是子文件夹
					copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
				}
			}
		} catch (Exception e) {
			System.out.println("复制整个文件夹内容操作出错");
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 移动文件到指定文件
	 * @param oldPath
	 *            文件路径
	 * @param newPath
	 *            目录
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void moveFile(String oldPath, String newPath) {
		copyFile(oldPath, newPath);
		delFile(oldPath);
	}

	/**
	 * 
	 * 
	 * @方法说明: 移动文件夹到指定目录
	 * @param oldPath
	 *            文件夹路径
	 * @param newPath
	 *            目录
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void moveFolder(String oldPath, String newPath) {
		copyFolder(oldPath, newPath);
		delFolder(oldPath);
	}

	/**
	 * 
	 * 
	 * @方法说明: 在某个文件夹创建新的文件夹
	 * @param pathOld
	 *            根文件夹
	 * @param pathNew
	 *            要创建的新的文件夹名
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void MAKE_DIR(String pathOld, String pathNew) {
		try {
			if (!(new File(pathOld).isDirectory())) {
				new File(pathOld);
				new File(pathOld + "/" + pathNew).mkdirs();
			} else {
				new File(pathOld + "/" + pathNew).mkdirs();
			}
		} catch (SecurityException e) {
			System.out.println("创建文件夹出错!" + e.getMessage());
		}
	}

	/**
	 * 
	 * 
	 * @方法说明: 修改文件夹的名称
	 * @param olddir
	 *            新的文件夹名
	 * @param newdir
	 *            老的文件夹名
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void modifydir(String olddir, String newdir) {
		try {
			new File(olddir).renameTo(new File(newdir));

		} catch (SecurityException e) {
			System.out.println("创建文件夹出错!" + e.getMessage());
		}
	}

	/**
	 * 
	 * 
	 * @方法说明:生成N位随即码
	 * @param len
	 * @return
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static String getRondom(int len) {
		StringBuffer buf = new StringBuffer(
				"a,b,c,d,e,f,g,h,i,g,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z");
		buf.append(",A,B,C,D,E,F,G,H,I,G,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z");
		// buf.append(",~,@,#,$,%,^,&,*,(,),_,+,|,`,.");
		buf.append(",1,2,3,4,5,6,7,8,9,0");
		String arr[] = buf.toString().split(",");
		String str = getPswd(arr, len);
		return str;
	}

	public static String getPswd(String[] arr, int len) {
		StringBuffer b = new StringBuffer();
		java.util.Random r;
		int k;
		for (int i = 0; i < len; i++) {
			r = new java.util.Random();
			k = r.nextInt();
			b.append(String.valueOf(arr[Math.abs(k % 62)]));
		}
		return b.toString();
	}

	/**
	 * 
	 * 
	 * @方法说明: 保存图片信息
	 * @param src
	 *            原来地址
	 * @param dst
	 *            保存地址
	 * @param path
	 * @param extr
	 * @param max
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static void copy(File src, File dst, String path, String extr,
			Integer max) {
		int BUFFER_SIZE = 16 * 1024;
		InputStream in = null;
		OutputStream out = null;
		try {
			in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
			out = new BufferedOutputStream(new FileOutputStream(dst),
					BUFFER_SIZE);
			byte[] buffer = new byte[BUFFER_SIZE];
			int len = 0;
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		if (extr.toLowerCase().equals(".gif")
				|| extr.toLowerCase().equals(".png")) {
		} else {
			try {
				Picfiles.saveMinPhoto(path, path, max, 1.1);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 
	 * 
	 * @方法说明:
	 * @param request
	 * @param picSrcFileName
	 *            上传的文件名
	 * @param picSrc
	 *            上传的文件
	 * @param dirpath
	 *            保存的目录
	 * @param maxpx
	 *            图片最大PX
	 * @return
	 * @作者:徐龙
	 * @日期:2010-5-25
	 */
	public static String getsrcpic(HttpServletRequest request,
			String picSrcFileName, File picSrc, String dirpath, Integer maxpx) {
		String picSrcsubfileName = Picfiles.getRondom(24);
		String picSrcextr = picSrcFileName.substring(picSrcFileName
				.lastIndexOf("."));
		String picSrcpath = request.getSession().getServletContext()
				.getRealPath(dirpath);
		String picSrcpic = dirpath + picSrcsubfileName + picSrcextr;
		String picSrcextrPath = picSrcpath + "/" + picSrcsubfileName
				+ picSrcextr;
		copy(picSrc, new File(picSrcextrPath), picSrcextrPath, picSrcextr,
				maxpx);
		return picSrcpic;
	}

	public static String getsrcFile(HttpServletRequest request,
			String picSrcFileName, File picSrc, String dirpath) {
		String picSrcsubfileName = Picfiles.getRondom(24);
		String picSrcextr = picSrcFileName.substring(picSrcFileName
				.lastIndexOf("."));
		String picSrcpath = request.getSession().getServletContext()
				.getRealPath(dirpath);
		String picSrcpic = dirpath + picSrcsubfileName + picSrcextr;
		String picSrcextrPath = picSrcpath + "/" + picSrcsubfileName
				+ picSrcextr;
		copyFile(picSrc, new File(picSrcextrPath));
		return picSrcpic;
	}

	public static void copyFile(File src, File dst) {
		int BUFFER_SIZE = 16 * 1024;
		try {
			InputStream in = null;
			OutputStream out = null;
			try {
				in = new BufferedInputStream(new FileInputStream(src),
						BUFFER_SIZE);
				out = new BufferedOutputStream(new FileOutputStream(dst),
						BUFFER_SIZE);
				byte[] buffer = new byte[BUFFER_SIZE];
				while (in.read(buffer) > 0) {
					out.write(buffer);
				}
			} finally {
				if (null != in) {
					in.close();
				}
				if (null != out) {
					out.close();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
